package rpg.factory
{
	import flash.display.BlendMode;
	import flash.utils.Dictionary;

	import rpg.Utils.GameUtils;
	import rpg.Utils.Log;
	import rpg.Utils.StringUtil;
	import rpg.Utils.Val;
	import rpg.animation.Animation;
	import rpg.animation.AnimationDescription;
	import rpg.animation.AvatarActionDescription;
	import rpg.animation.AvatarDescription;
	import rpg.avatar.Avatar;
	import rpg.avatar.AvatarComponent;
	import rpg.core.AnimationComponent;
	import rpg.core.AutoCastSpellComponent;
	import rpg.core.FlyAnimationComponent;
	import rpg.core.GameBase;
	import rpg.core.HpComponent;
	import rpg.core.MouseComponent;
	import rpg.core.NameComponent;
	import rpg.core.SceneAnimationComponent;
	import rpg.core.ShadowComponent;
	import rpg.data.HeroData;
	import rpg.manager.AnimationManager;
	import rpg.manager.GameManager;
	import rpg.render.RenderData;
	import rpg.role.Hero;
	import rpg.role.SceneObject;
	import rpg.state.Attack;
	import rpg.state.Dead;
	import rpg.state.Stand;
	import rpg.state.StateComponent;
	import rpg.state.Walk;

	public class GameFactory
	{
		public static const HERO : int = 1;

		private static var instance : GameFactory;

		private var animationManager : AnimationManager
		private var gm : GameManager;

		public static function getInstance() : GameFactory
		{
			if(instance == null)
			{
				instance = new GameFactory();
				instance.init();
			}
			return instance;
		}

		private function init() : void
		{
			gm = GameManager.getInstance();
			animationManager = AnimationManager.getInstance();
		}

		/**
		 * 根据id 创建人物
		 * @return
		 *
		 */
		public function createRole(id : String , isMe : Boolean = false) : GameBase
		{
			var avatarDes : AvatarDescription = animationManager.getAvatarDescription(id);
			var roleConfig : Object = animationManager.getDefaultHeroConfig(id);
			if(avatarDes == null)
			{
				Log.print("没有这种资源:" + id);
				return null;
			}
			if(roleConfig == null)
			{
				Log.print("没有默认的配置文件" + id);
				return null;
			}
			var parts : Array = roleConfig.parts;
			var hero : Hero = new Hero(avatarDes.name);
			hero.data = new HeroData();
			hero.data.race = roleConfig.id;

			var avatarComponent : AvatarComponent = new AvatarComponent(AvatarComponent);
			//必须先创建avatar再创建状态机
			var stateComponent : StateComponent = new StateComponent(StateComponent);
			var nameComponet : NameComponent = new NameComponent(NameComponent);
			var hpComponent : HpComponent = new HpComponent(HpComponent);
			var shadowComponent : ShadowComponent = new ShadowComponent(ShadowComponent);
			var autoCastSpellComponent : AutoCastSpellComponent = new AutoCastSpellComponent();

			hero.addComponent(avatarComponent);
			hero.addComponent(stateComponent);
			hero.addComponent(nameComponet);
			hero.addComponent(hpComponent);
			hero.addComponent(shadowComponent);
			hero.addComponent(autoCastSpellComponent);

			if(isMe)
			{
				var mouseComponet : MouseComponent = new MouseComponent(MouseComponent);
				hero.addComponent(mouseComponet);
				createTargetAnimation(hero , "guangquan" , Val.BOTTOM , 200);
			}

			hero.changeAvatar(avatarDes , parts);

			stateComponent.setRoleAnimation([Attack , Dead , Stand , Walk]);

			hero.registerd();
			return hero;
		}

		public function createAvatar(avatarDes : AvatarDescription , parts : Array) : Avatar
		{
			var actionsDirAnimation : Dictionary = animationManager.createAvatarAnimation(avatarDes , parts);
			var avavar : Avatar = new Avatar(avatarDes);
			avavar.actionsDirAnimation = actionsDirAnimation;
			return avavar;
		}

		/**
		 * 为一个对象添加一个动画组件
		 * @param target                添加目标
		 * @param animationID           动画ID
		 * @param zIndex                深度
		 * @param animationSpeed        播放速度
		 * @param animationDelayTime    延迟播放
		 * @param loops                 循环次数
		 * @param rotation              是否需要旋转
		 * @param blendMode             混合模式
		 * @return
		 *
		 */
		public function createTargetAnimation(target : GameBase , animationID : String , zIndex : int = 0 , animationSpeed : int = 0 , animationDelayTime : int = 0 , loops : int = 0 , rotation : Number = 0 , offsetX : int = 0 , offsetY : int = 0 , blendMode : String = BlendMode.NORMAL) : void
		{
			var animationComponent : AnimationComponent = createAnimationComponent(animationID , zIndex , animationSpeed , animationDelayTime , loops , rotation , offsetX , offsetY , blendMode);
			target.addComponent(animationComponent);
		}

		/**
		 * 创建一个动画组件
		 * @param animationID           动画ID
		 * @param zIndex                深度
		 * @param animationSpeed        播放速度
		 * @param animationDelayTime    延迟播放
		 * @param loops                 循环次数
		 * @param rotation              是否需要旋转
		 * @param blendMode             混合模式
		 *
		 */
		public function createAnimationComponent(animationID : String , zIndex : int = 0 , animationSpeed : int = 0 , animationDelayTime : int = 0 , loops : int = 0 , rotation : Number = 0 , offsetX : int = 0 , offsetY : int = 0 , blendMode : String = BlendMode.NORMAL) : AnimationComponent
		{
			var aniamtion : Animation = animationManager.createAnimation(animationID);
			aniamtion.setDration(animationSpeed);
			var animationComponent : AnimationComponent = new AnimationComponent(animationID);
			animationComponent.offsetX = offsetX;
			animationComponent.offsetY = offsetY;
			animationComponent.setAnimation(aniamtion , zIndex , animationDelayTime , loops);
			animationComponent.setRotate(rotation);
			animationComponent.blendMode = blendMode;
			return animationComponent;
		}

		/**
		 * 为一个对象添加一个动画组件
		 * @param target                添加目标
		 * @param animationID           动画ID
		 * @param zIndex                深度
		 * @param animationSpeed        播放速度
		 * @param animationDelayTime    延迟播放
		 * @param loops                 循环次数
		 * @param rotation              是否需要旋转
		 * @param blendMode             混合模式
		 * @return
		 *
		 */
		public function createSceneAnimation(target : SceneObject , animationID : String , zIndex : int = 0 , animationSpeed : int = 0 , animationDelayTime : int = 0 , loops : int = 0 , rotation : Number = 0 , offsetX : int = 0 , offsetY : int = 0 , blendMode : String = BlendMode.NORMAL) : void
		{
			var animationComponent : SceneAnimationComponent = createSceneAnimationComponent(animationID , zIndex , animationSpeed , animationDelayTime , loops , rotation , offsetX , offsetY , blendMode);
			animationComponent.setTargetXY(target.mapX , target.mapY);
			gm.sceneObject.addComponent(animationComponent);
		}

		/**
		 * 创建一个场景动画组件
		 * @param animationID           动画ID
		 * @param zIndex                深度
		 * @param animationSpeed        播放速度
		 * @param animationDelayTime    延迟播放
		 * @param loops                 循环次数
		 * @param rotation              是否需要旋转
		 * @param blendMode             混合模式
		 *
		 */
		public function createSceneAnimationComponent(animationID : String , zIndex : int = 0 , animationSpeed : int = 0 , animationDelayTime : int = 0 , loops : int = 0 , rotation : Number = 0 , offsetX : int = 0 , offsetY : int = 0 , blendMode : String = BlendMode.NORMAL) : SceneAnimationComponent
		{
			var aniamtion : Animation = animationManager.createAnimation(animationID);
			aniamtion.setDration(animationSpeed);
			var animationComponent : SceneAnimationComponent = new SceneAnimationComponent(animationID);
			animationComponent.offsetX = offsetX;
			animationComponent.offsetY = offsetY;
			animationComponent.setAnimation(aniamtion , zIndex , animationDelayTime , loops , rotation);
			animationComponent.blendMode = blendMode;
			return animationComponent;
		}

		/**
		 * 创建弹道飞行效果
		 * @param animationID      动画ID
		 * @param flightSpeed      飞行速度
		 * @param mapX             开始地点X
		 * @param mapY			   开始地点Y
		 * @param targetX  		   目标地点X
		 * @param targetY		   目标地点Y
		 * @param needRotate       是否需要旋转
		 * @param animationSpeed   动画播放速度
		 * @param blendMode        混合模式
		 */
		public function createFlyAnimation(animationID : String , flightSpeed : Number , mapX : int , mapY : int , targetX : int , targetY : int , needRotate : Boolean , animationSpeed : int = 90 , blendMode : String = BlendMode.NORMAL) : void
		{
			var aniamtion : Animation = animationManager.createAnimation(animationID);
			aniamtion.setDration(animationSpeed);
			var rotation : int = 0;
			if(needRotate)
				rotation = GameUtils.getRotation(mapX , mapY , targetX , targetY);
			mapX += GameUtils.cosD(rotation) * 20;
			mapY += GameUtils.sinD(rotation) * 20;
			var flyAnimationComponent : FlyAnimationComponent = new FlyAnimationComponent(animationID);
			flyAnimationComponent.setAnimation(aniamtion , 2 , 0 , 0);
			flyAnimationComponent.setRotate(rotation);
			flyAnimationComponent.blendMode = blendMode;
			flyAnimationComponent.setStartPosition(mapX , mapY);
			flyAnimationComponent.setTargetPosition(targetX , targetY);
			flyAnimationComponent.speed = flightSpeed;
			gm.sceneObject.addComponent(flyAnimationComponent);
		}

		/**
		 * 创建弹道飞行跟随目标效果
		 * @param animationID      动画ID
		 * @param flightSpeed      飞行速度
		 * @param mapX             开始地点X
		 * @param mapY			   开始地点Y
		 * @param targetX  		   目标地点X
		 * @param targetY		   目标地点Y
		 * @param needRotate       是否需要旋转
		 * @param animationSpeed   动画播放速度
		 * @param blendMode        混合模式
		 */
		public function createFollowFlyAnimation(animationID : String , flightSpeed : Number , mapX : int , mapY : int , target : SceneObject , needRotate : Boolean , animationSpeed : int = 90 , rotation : int = 0 , blendMode : String = BlendMode.NORMAL) : void
		{
			var aniamtion : Animation = animationManager.createAnimation(animationID);
			aniamtion.setDration(animationSpeed);
			var flyAnimationComponent : FlyAnimationComponent = new FlyAnimationComponent(animationID);
			if(needRotate)
			{
				//var rotation : int = GameUtils.getRotation(mapX , mapY , target.mapX , target.mapY);
				mapX += GameUtils.cosD(rotation) * 50;
				mapY += GameUtils.sinD(rotation) * 50;
				flyAnimationComponent.setRotate(rotation);
			}
			flyAnimationComponent.needRotate = needRotate;
			flyAnimationComponent.setAnimation(aniamtion , 2 , 0 , 0);
			flyAnimationComponent.blendMode = blendMode;
			flyAnimationComponent.setStartPosition(mapX , mapY);
			flyAnimationComponent.setTarget(target);
			flyAnimationComponent.speed = flightSpeed;
			gm.sceneObject.addComponent(flyAnimationComponent);
		}
	}
}